package com.twu.biblioteca;

import java.io.IOException;
import java.util.ArrayList;

/**
 * User: akerber
 * Date: 1/25/13
 * Time: 1:47 PM
 */

public class MainMenu {


    public static enum OPTIONS {
        SHOW_ALL_BOOKS("View all the books"),
        RESERVE_A_BOOK("Reserve a Book"),
        USER_INFORMATION("Check membership details"),
        SHOW_ALL_MOVIES("View all the movies"),
        EXIT("Exit"),
        LOGIN("Login"),
        OUT_OF_RANGE(""); //let it here as an option?

        private String menuMessage;

        private OPTIONS(String message){
            this.menuMessage = message;
        }

        public String getMenuMessage(){
           return menuMessage;
        }
    };

    ArrayList<OPTIONS> availableOptionsWhenLoggedIn;
    ArrayList<OPTIONS> availableOptionsWhenNotLoggedIn;
    ArrayList<OPTIONS> currentAvailableOptions;

    private MovieCatalog movieCatalog;
    private DisplayMessage displayMessage;
    private UserInputReader userInputReader;
    private UserSession userSession;
    private UsersRepository usersRepository;
    private BookCatalog bookCatalog;
    private Authenticator authenticator;

    public MainMenu(BookCatalog bookCatalog, MovieCatalog movieCatalog, DisplayMessage displayMessage, UserInputReader userInputReader, UserSession userSession, UsersRepository usersRepository){
        this.bookCatalog = bookCatalog;
        this.movieCatalog = movieCatalog;
        this.displayMessage = displayMessage;
        this.userInputReader = userInputReader;
        this.userSession = userSession;
        this.usersRepository = usersRepository;
        initializeMenuOptionsLogged();
        initializeMenuOptionsNotLogged();
        this.currentAvailableOptions = availableOptionsWhenNotLoggedIn;
        authenticator = new Authenticator(usersRepository,userSession);
    }

    private void initializeMenuOptionsLogged(){
        availableOptionsWhenLoggedIn = new ArrayList<OPTIONS>();
        availableOptionsWhenLoggedIn.add(OPTIONS.SHOW_ALL_BOOKS);
        availableOptionsWhenLoggedIn.add(OPTIONS.RESERVE_A_BOOK);
        availableOptionsWhenLoggedIn.add(OPTIONS.USER_INFORMATION);
        availableOptionsWhenLoggedIn.add(OPTIONS.SHOW_ALL_MOVIES);
        availableOptionsWhenLoggedIn.add(OPTIONS.EXIT);


    }

    public void initializeMenuOptionsNotLogged(){
        availableOptionsWhenNotLoggedIn = new ArrayList<OPTIONS>();
        availableOptionsWhenNotLoggedIn.add(OPTIONS.LOGIN);
        availableOptionsWhenNotLoggedIn.add(OPTIONS.SHOW_ALL_BOOKS);
        availableOptionsWhenNotLoggedIn.add(OPTIONS.SHOW_ALL_MOVIES);
        availableOptionsWhenNotLoggedIn.add(OPTIONS.USER_INFORMATION);
        availableOptionsWhenNotLoggedIn.add(OPTIONS.EXIT);

    }

    public void selectOption(OPTIONS selectedOption) throws IOException {
        switch(selectedOption){
            case USER_INFORMATION:
                if(userSession.isLogged()){
                    displayMessage.showLoggedUserInformationMessage();
                }
                else displayMessage.showUserInformationMessage();
                break;
            case OUT_OF_RANGE:
                displayMessage.showInvalidSelectedOptionMessage();
                break;
            case SHOW_ALL_BOOKS:
                bookCatalog.showAllBooks();
                break;
            case RESERVE_A_BOOK:
                if(userSession.isLogged()){
                    processReserveBookOption();
                }
                break;
            case EXIT:
                System.exit(0);
                break;
            case SHOW_ALL_MOVIES:
                movieCatalog.showAllMovies();
                break;
            case LOGIN: login();
                break;
        }

    }

    private void login() throws IOException {
        User user;
        displayMessage.showInformUserName();
        String userName = userInputReader.processUserInputUsername();
        displayMessage.showInformPassword();
        String password = userInputReader.processUserInputPassword();
        user = new User(userName,password);
        boolean authenticated = authenticator.authenticate(user);
        if(!authenticated){
            displayMessage.showLoginError();
        }

    }

    private void processReserveBookOption() throws IOException {
        boolean wasReserved;
        String bookName = userInputReader.processUserInputBookName();
        Book book = new Book(bookName);
        wasReserved = bookCatalog.reserve(book);
        if(wasReserved){
           displayMessage.showSuccessfullyReservedBookMessage();
        } else displayMessage.showBookNotAvailableMessage();

    }

    public void displayMainMenu() throws IOException {
        boolean isLoggedIn = userSession.isLogged();
        int selectedOptionNumber;
        OPTIONS selectedOption;
        do {
            showMainMenuOptions(isLoggedIn);
            selectedOptionNumber = userInputReader.processUserInputToInt();
            if(isValidOption(selectedOptionNumber)){
                selectedOption = currentAvailableOptions.get(selectedOptionNumber);
            } else selectedOption = OPTIONS.OUT_OF_RANGE;
            selectOption(selectedOption);
        } while (selectedOption !=  OPTIONS.EXIT);

    }

    private boolean isValidOption(int selectedOptionNumber) {
        return selectedOptionNumber >=0 && selectedOptionNumber<currentAvailableOptions.size();
    }

    public void showMainMenuOptions(boolean isLoggedIn){
        displayMessage.showSelectAnOptionMessage();
        if (isLoggedIn){
            displayMessage.showMainMenuAvailableOptionsWhenLoggedIn(currentAvailableOptions);
        } else displayMessage.showMainMenuAvailableOptionsWhenNotLoggedIn(currentAvailableOptions);
    }


}
